﻿using Leeder;
using Leeder.PLC;
using Leeder.PLC.Mitsubishi.MC.FX;
using PickingGuide.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PickingGuide.Handle
{
    public class PlcHandler
    {

        object lockobj = new object();
        /// <summary>
        /// 三菱FX3U
        /// </summary>
        FXHandler fx3U;

        PlcConnectModel _PlcConnect;


        private PlcHandler() { }
        private static PlcHandler instance = new PlcHandler();
        public static PlcHandler getInstance()
        {
            if (instance == null)
                instance = new PlcHandler();
            return instance;
        }

        public bool Init(PlcConnectModel connect)
        {
            _PlcConnect = connect;
            CheckPLCstatus(connect);
            return true;
        }

        /// <summary>
        /// 获取PLC数据
        /// </summary>
        /// <param name="plcAddresModel"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public string GetPlcNum(PlcAddresModel plcAddresModel)
        {
            //FileLogger.INFO($"开始读取地址{address}...");
            PLCAddress addStart = new PLCAddress();
            addStart.Area = plcAddresModel.Area;
            //addStart.Area = plcAddresModel.Area;
            //addStart.Address = 0x102;
            //addStart.Address = Convert.ToUInt16(plcAddresModel.Address, 16);
            addStart.Address = ushort.Parse(plcAddresModel.Address);
            addStart.DataLength = ushort.Parse(plcAddresModel.DataLength.ToString());

            CheckPLCstatus(_PlcConnect);

            if (plcAddresModel.PlcDataType == 0)
            {
                addStart.DataType = PLCDataType.Bit;
            }else
            {
                addStart.DataType = PLCDataType.Char;
            }

            SubmitResultOutput read = fx3U.Read(addStart);
            if (!read.IsSuccess)
            {
                throw new Exception(read.Dsca);
            }
            //if (!read.IsEffective) return "0";
            if (read.ReturnObj != null)
            {
                byte[] bts = (byte[])read.ReturnObj;
                uint num = 0;
                if (bts.Length < 2) num = bts[0];
                else BitConverter.ToUInt16(bts, 0);
                //uint num = BitConverter.ToUInt16(bts, 0);
                string s = BitConverter.ToString(bts);
                //logObj.Info($"从PLC读取到byte : {s}");

                if (plcAddresModel.PlcDataType == 0)
                {
                    bool[] arrB = fx3U.ConvertBit(bts);
                    foreach (bool flag in arrB)
                    {
                        if (flag) return "1";
                    }
                }
                return s;
            }
            return "";
        }

        /// <summary>
        /// 检查PLC状态
        /// </summary>
        private void CheckPLCstatus(PlcConnectModel plcConnect)
        {
            try {
                if (fx3U == null)
                {
                    lock (lockobj)
                    {
                        if (fx3U == null)
                        {
                            fx3U = new FXHandler(PLCModel.FX3, plcConnect.IP, plcConnect.Port);
                        }
                    }
                }
            } catch (Exception e) {
                throw e;
            }
        }

        /// <summary>
        /// 写PLC数据
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="carInfo"></param>
        /// <returns></returns>
        public bool SendPlcData(PlcAddresModel plcAddres, int value)
        {
            CheckPLCstatus(_PlcConnect);

            try
            {
                PLCAddress addStart = new PLCAddress();
                addStart.Area = plcAddres.Area;
                addStart.Address = ushort.Parse(plcAddres.Address);
                addStart.DataLength = ushort.Parse(plcAddres.DataLength.ToString());

                byte[] bts = BitConverter.GetBytes(value);
                addStart.DataValue = bts;
                SubmitResultOutput res = fx3U.Write(addStart);

                if (res.IsSuccess)
                {
                    //logObj.Debug($"写数据到PLC的,地址:{plc.Sign}{plc.Address},值:{carInfo.Code}");
                    return true;
                }
                else
                {
                    //logObj.Debug($"写数据到PLC    失败！  ,地址:{plc.Sign}{plc.Address},值:{carInfo.Code}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
                //logObj.Error(ex.ToString());
                return false;
            }
        }
    }
}
